package com.ruoci.redis.distributedlocks;

import com.ruoci.redis.constants.BusinessConstants;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.exception.ExceptionUtils;
import org.redisson.api.RLock;
import org.redisson.api.RedissonClient;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.annotation.Resource;


/**
 * @Author yang
 *
 **/
@Slf4j
@RestController
public class RedissonController {

    @Resource
    private RedissonClient redissonClient;

    @Resource
    private RedisTemplate redisTemplate;

    /**
     *
     * 30秒钟自动解锁，自己指定解锁时间redis不会自动续期
     * lock.lock(30, TimeUnit.SECONDS);
     * @return
     */
    @GetMapping("/redisson/lock")
    public String lock() {
        //分布式锁的意义在于多进程同一个key串行
        RLock lock = redissonClient.getLock(BusinessConstants.PRODUCT_LOCK);
        long startMillis = 0;
        long endMillis = 0;
        try {
            //lock.lock()默认加锁时间是30s,自动续期1/3s,
            lock.lock();
            startMillis = System.currentTimeMillis();
            //真正操作商品库存
            int stock = Integer.parseInt(String.valueOf(redisTemplate.opsForValue().get(BusinessConstants.STOCK)));
            if (stock > 0) {
                int realStock = stock - 1;
                redisTemplate.opsForValue().set(BusinessConstants.STOCK, realStock);
                log.info("扣减成功，剩余库存：" + realStock);
            } else {
                log.info("扣减失败，库存不足！");
            }
            endMillis = System.currentTimeMillis();
        } catch (Exception e) {
            log.error(ExceptionUtils.getStackTrace(e));
        } finally {
            // 释放锁
            lock.unlock();
        }
        log.info("耗时: " + (endMillis - startMillis));
        String end = "end";
        return end;
    }


}
